<!DOCTYPE html>
<html lang="en">
<head>

    <meta charset="utf-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />

    <title>New Threat: B1txor20, A Linux Backdoor Using DNS Tunnel</title>
    <meta name="HandheldFriendly" content="True" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />

    <link rel="stylesheet" type="text/css" href="/assets/built/screen.css?v=a1b70de19f" />

    <link rel="shortcut icon" href="/favicon.png" type="image/png" />
    <link rel="canonical" href="https://blog.netlab.360.com/b1txor20-use-of-dns-tunneling_en/" />
    <meta name="referrer" content="no-referrer-when-downgrade" />
    <link rel="amphtml" href="https://blog.netlab.360.com/b1txor20-use-of-dns-tunneling_en/amp/" />
    
    <meta property="og:site_name" content="360 Netlab Blog - Network Security Research Lab at 360" />
    <meta property="og:type" content="article" />
    <meta property="og:title" content="New Threat: B1txor20, A Linux Backdoor Using DNS Tunnel" />
    <meta property="og:description" content="Background
Since the Log4J vulnerability  was exposed, we see more and more malware jumped
on the wagon, Elknot, Gafgyt, Mirai are all too familiar, on February 9, 2022,
360Netlab&#x27;s honeypot system captured an unknown ELF file propagating through the
Log4J vulnerability. What stands out is that the network traffic generated by
this sample triggered a DNS Tunnel alert  in our system, We decided to take a
close look, and indeed, it is a new botnet family, which we named B1txor20 
based on its prop" />
    <meta property="og:url" content="https://blog.netlab.360.com/b1txor20-use-of-dns-tunneling_en/" />
    <meta property="article:published_time" content="2022-03-15T14:00:00.000Z" />
    <meta property="article:modified_time" content="2022-03-15T14:00:00.000Z" />
    <meta property="article:tag" content="Botnet" />
    <meta property="article:tag" content="DNS Tunnel" />
    <meta property="article:tag" content="Backdoor" />
    
    <meta name="twitter:card" content="summary" />
    <meta name="twitter:title" content="New Threat: B1txor20, A Linux Backdoor Using DNS Tunnel" />
    <meta name="twitter:description" content="Background
Since the Log4J vulnerability  was exposed, we see more and more malware jumped
on the wagon, Elknot, Gafgyt, Mirai are all too familiar, on February 9, 2022,
360Netlab&#x27;s honeypot system captured an unknown ELF file propagating through the
Log4J vulnerability. What stands out is that the network traffic generated by
this sample triggered a DNS Tunnel alert  in our system, We decided to take a
close look, and indeed, it is a new botnet family, which we named B1txor20 
based on its prop" />
    <meta name="twitter:url" content="https://blog.netlab.360.com/b1txor20-use-of-dns-tunneling_en/" />
    <meta name="twitter:label1" content="Written by" />
    <meta name="twitter:data1" content="Alex.Turing" />
    <meta name="twitter:label2" content="Filed under" />
    <meta name="twitter:data2" content="Botnet, DNS Tunnel, Backdoor" />
    <meta name="twitter:site" content="@360Netlab" />
    <meta name="twitter:creator" content="@TuringAlex" />
    
    <script type="application/ld+json">
{
    "@context": "https://schema.org",
    "@type": "Article",
    "publisher": {
        "@type": "Organization",
        "name": "360 Netlab Blog - Network Security Research Lab at 360",
        "logo": "https://blog.netlab.360.com/content/images/2019/02/netlab-brand-5.png"
    },
    "author": {
        "@type": "Person",
        "name": "Alex.Turing",
        "image": {
            "@type": "ImageObject",
            "url": "https://blog.netlab.360.com/content/images/2019/06/turing.PNG",
            "width": 1363,
            "height": 1363
        },
        "url": "https://blog.netlab.360.com/author/alex/",
        "sameAs": [
            "https://twitter.com/TuringAlex"
        ]
    },
    "headline": "New Threat: B1txor20, A Linux Backdoor Using DNS Tunnel",
    "url": "https://blog.netlab.360.com/b1txor20-use-of-dns-tunneling_en/",
    "datePublished": "2022-03-15T14:00:00.000Z",
    "dateModified": "2022-03-15T14:00:00.000Z",
    "keywords": "Botnet, DNS Tunnel, Backdoor",
    "description": "Background\nSince the Log4J vulnerability  was exposed, we see more and more malware jumped\non the wagon, Elknot, Gafgyt, Mirai are all too familiar, on February 9, 2022,\n360Netlab&#x27;s honeypot system captured an unknown ELF file propagating through the\nLog4J vulnerability. What stands out is that the network traffic generated by\nthis sample triggered a DNS Tunnel alert  in our system, We decided to take a\nclose look, and indeed, it is a new botnet family, which we named B1txor20 \nbased on its prop",
    "mainEntityOfPage": {
        "@type": "WebPage",
        "@id": "https://blog.netlab.360.com/"
    }
}
    </script>

    <script src="/public/ghost-sdk.min.js?v=a1b70de19f"></script>
<script>
ghost.init({
	clientId: "ghost-frontend",
	clientSecret: "2a7213b591a9"
});
</script>
    <meta name="generator" content="Ghost 2.13" />
    <link rel="alternate" type="application/rss+xml" title="360 Netlab Blog - Network Security Research Lab at 360" href="https://blog.netlab.360.com/rss/" />
    
<script>
  (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
  (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
  m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
  })(window,document,'script','https://www.google-analytics.com/analytics.js','ga');

  ga('create', 'UA-83587830-1', 'auto');
  ga('send', 'pageview');

</script>

<!-- Fix first paragraph font size -->
<style type="text/css">
 .post-template .post-content > p:first-child {font-size: 1em;}
</style>

</head>
<body class="post-template tag-botnet tag-dns-tunnel tag-backdoor">

    <div class="site-wrapper">

             <header
    class="site-header outer">
    <div class="inner">
        <nav class="site-nav">
    <div class="site-nav-left">
                <a class="site-nav-logo" href="https://blog.netlab.360.com"><img src="https://blog.netlab.360.com/content/images/2019/02/netlab-brand-5.png" alt="360 Netlab Blog - Network Security Research Lab at 360" /></a>
            <ul class="nav" role="menu">
    <li class="nav-botnet" role="menuitem"><a href="https://blog.netlab.360.com/tag/botnet/">Botnet</a></li>
    <li class="nav-dnsmon" role="menuitem"><a href="https://blog.netlab.360.com/tag/dnsmon/">DNSMon</a></li>
    <li class="nav-ddos" role="menuitem"><a href="https://blog.netlab.360.com/tag/ddos/">DDoS</a></li>
    <li class="nav-passivedns" role="menuitem"><a href="https://blog.netlab.360.com/tag/pdns/">PassiveDNS</a></li>
    <li class="nav-mirai" role="menuitem"><a href="https://blog.netlab.360.com/tag/mirai/">Mirai</a></li>
    <li class="nav-dta" role="menuitem"><a href="https://blog.netlab.360.com/tag/dta/">DTA</a></li>
</ul>

    </div>
    <div class="site-nav-right">
        <div class="social-links">
                <a class="social-link social-link-tw" href="https://twitter.com/360Netlab" title="Twitter" target="_blank" rel="noopener"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32"><path d="M30.063 7.313c-.813 1.125-1.75 2.125-2.875 2.938v.75c0 1.563-.188 3.125-.688 4.625a15.088 15.088 0 0 1-2.063 4.438c-.875 1.438-2 2.688-3.25 3.813a15.015 15.015 0 0 1-4.625 2.563c-1.813.688-3.75 1-5.75 1-3.25 0-6.188-.875-8.875-2.625.438.063.875.125 1.375.125 2.688 0 5.063-.875 7.188-2.5-1.25 0-2.375-.375-3.375-1.125s-1.688-1.688-2.063-2.875c.438.063.813.125 1.125.125.5 0 1-.063 1.5-.25-1.313-.25-2.438-.938-3.313-1.938a5.673 5.673 0 0 1-1.313-3.688v-.063c.813.438 1.688.688 2.625.688a5.228 5.228 0 0 1-1.875-2c-.5-.875-.688-1.813-.688-2.75 0-1.063.25-2.063.75-2.938 1.438 1.75 3.188 3.188 5.25 4.25s4.313 1.688 6.688 1.813a5.579 5.579 0 0 1 1.5-5.438c1.125-1.125 2.5-1.688 4.125-1.688s3.063.625 4.188 1.813a11.48 11.48 0 0 0 3.688-1.375c-.438 1.375-1.313 2.438-2.563 3.188 1.125-.125 2.188-.438 3.313-.875z"/></svg>
</a>
        </div>
            <a class="rss-button" href="https://feedly.com/i/subscription/feed/https://blog.netlab.360.com/rss/" title="RSS" target="_blank" rel="noopener"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><circle cx="6.18" cy="17.82" r="2.18"/><path d="M4 4.44v2.83c7.03 0 12.73 5.7 12.73 12.73h2.83c0-8.59-6.97-15.56-15.56-15.56zm0 5.66v2.83c3.9 0 7.07 3.17 7.07 7.07h2.83c0-5.47-4.43-9.9-9.9-9.9z"/></svg>
</a>
    </div>
</nav>
    </div>
    </header>


    <main id="site-main" class="site-main outer">
        <div class="inner">

            <article class="post-full post tag-botnet tag-dns-tunnel tag-backdoor no-image">

                <header class="post-full-header">
                    <section class="post-full-meta">
                        <time class="post-full-meta-date" datetime="2022-03-15">15 March                            2022</time>
                        <span class="date-divider">/</span> <a href="/tag/botnet/">Botnet</a>
                    </section>
                    <h1 class="post-full-title">New Threat: B1txor20, A Linux Backdoor Using DNS Tunnel</h1>
                </header>


                <section class="post-full-content">
                    <div class="post-content">
                        <h2 id="background">Background</h2>
<p>Since the <strong>Log4J vulnerability</strong> was exposed, we see more and more malware jumped on the wagon, Elknot, Gafgyt, Mirai are all too familiar, on February 9, 2022, 360Netlab's honeypot system captured an unknown ELF file propagating through the Log4J vulnerability. What stands out is that the network traffic generated by this sample triggered a <strong>DNS Tunnel alert</strong> in our system, We decided to take a close look, and indeed, it is a new botnet family, which we named <strong>B1txor20</strong> based on its propagation using the file name &quot;b1t&quot;, the XOR encryption algorithm, and the RC4 algorithm key length of 20 bytes.</p>
<p>In short, B1txor20 is a Backdoor for the Linux platform, which uses DNS Tunnel technology to build C2 communication channels. In addition to the traditional backdoor functions, B1txor20 also has functions such as opening Socket5 proxy and remotely downloading and installing Rootkit.</p>
<p>Another interesting point is that we found that many developed features are not put into use (in IDA, there is no cross-reference); some features have bugs. we presume that the author of B1txor20 will continue to improve and open different features according to different scenarios, so maybe we will meet B1txor20's siblings in the future.</p>
<h2 id="b1txor20overview">B1txor20 Overview</h2>
<p>We have captured a total of four different B1txor20 samples, their functions are almost the same, a total of 15 function numbers are supported, according to these functions, B1txor20 can be characterized as: <strong>using DNS Tunnel to establish C2 channel</strong>, support direct connection and relay, while using <code>ZLIB compression, RC4 encryption, BASE64 encoding</code>to protect the traffic of the backdoor Trojan, mainly targets <code>ARM, X64 CPU</code> architecture of the Linux platform.</p>
<p>The main features currently supported are shown below.</p>
<ol>
<li>SHELL</li>
<li>Proxy</li>
<li>Execute arbitrary commands</li>
<li>Install Rootkit</li>
<li>Upload sensitive information</li>
</ol>
<p>Its basic flowchart is shown below.</p>
<img src="https://blog.netlab.360.com/content/images/2022/03/b1t_net.png" width="860px">
<h2 id="reverseanalysis">Reverse Analysis</h2>
<p>We choose the sample on February 09, 2022 as the main object of analysis, and its basic information is shown as follows.</p>
<pre><code>MD5:0a0c43726fd256ad827f4108bdf5e772

ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.18, stripped

Packer:None
</code></pre>
<p>The sample of B1txor20 is dynamically linked, so it is relatively easy to reverse. Simply put, when B1txor20 executes, it will first disguise itself as a [netns] process, run a single instance through the PID file<code>/var/run/.netns.pid</code>, and then use <code>/etc/machine-id</code>, <code>/tmp/.138171241</code> or <code>/dev/urandom</code> to generate the BotID, then decrypt the domain name used for DNS Tunnel and the RC4 secret key used to encrypt the traffic and test the connectivity of the DNS server, and finally use DNS Tunnel to send registration information to C2 and wait for the execution of the commands issued by C2. Here we will not go into details about the regular functions, we will take a look at the DNS Tunnel implementation of the B1txor20.</p>
<h2 id="generatingbotid">Generating Bot ID</h2>
<p>B1txor20 uses the following code snippet to read 32 bytes from <code>/etc/machine-id</code>, or <code>/tmp/.138171241</code>, for generating BotId, and if it fails, a 16 bytes of data will be generated via /dev/urandom and will be written to the previous 2 files.</p>
<img src="https://blog.netlab.360.com/content/images/2022/03/b1t_id.png" width="860px">
<p>The following code snippet shows the process of BotId calculation.</p>
<img src="https://blog.netlab.360.com/content/images/2022/03/b1t_calc.png" width="860px">
<p>Taking the machine-id value<code>ab3b49d10ec42c38b1093b8ce9ad12af</code>of our VM as an example, the following equivalent python code can be used to calculate the value of BotId as <strong>0x125d</strong>.</p>
<pre><code class="language-python">import struct
id='ab3b49d10ec42c38b1093b8ce9ad12af'
values=struct.unpack(&quot;&lt;16H&quot;,id)
sum=0
for i in values:
    sum ^= i
print hex(sum)
if sum&amp;0xff &lt;0xf:
    sum+=0x10
if sum&gt;&gt;8 &lt; 0xf:
    sum+=0x1000
print hex(sum)   # sum=0x125d

</code></pre>
<h2 id="decryption">Decryption</h2>
<p>B1txor20 decrypts the domain name and RC4 secret key stored in the sample with the following code snippet.</p>
<img src="https://blog.netlab.360.com/content/images/2022/03/b1t_dec.png" width="860px">
<p>Its principle is very simple, it is a single-byte xor operation, where xor_key is<code>49 D3 4F A7 A2 BC 4D FA 40 CF A6 32 31 E9 59 A1</code>.</p>
<img src="https://blog.netlab.360.com/content/images/2022/03/b1t_xor.png" width="860px">
<p>The decryption process is equivalent to the CyberChef implementation in the following figure, which shows that the domain name is<code>.dns.webserv.systems</code> and the RC4 secret key is <code>EnLgLKHhy20f8A1dX85l</code>.</p>
<img src="https://blog.netlab.360.com/content/images/2022/03/b1t_chef_xor.png" width="860px">
<h2 id="measuretheconnectivityofdnsservers">Measure the connectivity of DNS servers</h2>
<p>B1txor20 tests the connectivity of 3 DNS (8.8.8.8:53, 8.8.8.4:53, 194.165.16.24:443) servers with the following code snippet.</p>
<img src="https://blog.netlab.360.com/content/images/2022/03/b1t_dns.png" width="860px">
<p>The principle is to use <code>res_mkquery</code> API to build the DNS request message for &quot;google.com&quot;, then send the request via <code>res_send</code>, and as long as it can be sent successfully, the network is considered to be connected to the corresponding DNS server, and they are saved for subsequent use.</p>
<img src="https://blog.netlab.360.com/content/images/2022/03/b1t_test.png" width="860px">
<p>The actual traffic generated by Bot and 194.165.16.24 is as follows.</p>
<img src="https://blog.netlab.360.com/content/images/2022/03/b1t_show.png" width="860px">
<h2 id="cccommunication">C&amp;C Communication</h2>
<p>When the above preparations are completed, B1txor20 enters the final stage, using DNS Tunnel to establish communication with C2 and wait for the execution of the commands sent by C2.</p>
<img src="https://blog.netlab.360.com/content/images/2022/03/b1t_final.png" width="860px">
<p>Generally speaking, the scenario of malware using DNS Tunnel is as follows:</p>
<blockquote>
<p>Bot sends the stolen sensitive information, command execution results, and any other information that needs to be delivered, after hiding it using specific encoding techniques, to C2 as a DNS request; After receiving the request, C2 sends the payload to the Bot side as a response to the DNS request. In this way, Bot and C2 achieve communication with the help of DNS protocol.</p>
</blockquote>
<p>In such a network structure, there are 3 key points:</p>
<p>1:C2 must support the DNS protocol<br>
2: Specific encoding techniques<br>
3: The way DNS requests are sent</p>
<p>The following section will analyze the technical details of B1txor20's communication around these points, in conjunction with the traffic generated by B1txor20 in practice.<br>
<img src="https://blog.netlab.360.com/content/images/2022/03/b1t_packet.png" width="860px"></p>
<h2 id="0x01locatingc2">0x01:Locating C2</h2>
<p>Through the traffic in the above figure, we can see that the SLD used by B1txor20 is webserv.systems, and using the DIG command, we can see that this SLD is point to IP 194.165.16.24; and the DNS resolution service is turned on at this IP 194, so we can determine that the C2 of B1txor20 is exactly 194.165.16.24.</p>
<img src="https://blog.netlab.360.com/content/images/2022/03/b1t_dnstxt.png" width="860px">
<h2 id="0x02generatetunneldomainname">0x02:Generate Tunnel domain name</h2>
<p>The format of B1txor20's Tunnel domain name is<code>Base64-Like String+.dns.websrv.systems</code>. It is obvious that the front Base64 string is the information sent by Bot to C2, <strong>how is it generated</strong>?</p>
<p>First, the B1txor20 packet has a pre-construction process, which can be seen in the format of<code>0xFF + BotId + 0xFF + Stage + 0xFF + TaskInfo</code>, <strong>0xFF</strong> is used to separate different items, and when the construction is finished, according to different Stage values, different tasks will fill the<code>TaskInfo</code>section accordingly.</p>
<img src="https://blog.netlab.360.com/content/images/2022/03/b1t_pre.png" width="860px">
<p>Take the above task as an example, the Stage value is 1. Through the <code>gather_info</code> function, the information of &quot;sysinfo_uptime,uid,hostname&quot; is filled into <code>TaskInfo</code>, and they are separated by<strong>0x0a</strong>.</p>
<img src="https://blog.netlab.360.com/content/images/2022/03/b1t_reg.png" width="860px">
<p>When the required information is ready, B1txor20 uses the<strong>process_query</strong>function to further process the above information, which includes three processes: <strong>ZLIB compression, RC4 encryption, and Base64 encoding</strong>.</p>
<img src="https://blog.netlab.360.com/content/images/2022/03/b1t_process.png" width="860px">
<p>The secret key used in RC4 encryption is the string &quot;EnLgLKHhy20f8A1dX85l&quot; mentioned in the previous decryption section, and the Alphabet String used in Base64 is <code>ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789^_</code>.</p>
<p>Finally, B1txor20 adds 1 byte of status and 4 bytes of random string before the Base64 string generated above, and then splices it with domain, which is the final domain name to be queried. The value of status is ['0', '1', '2'], 0 means that the current query is truncated, the subsequent query and the current should be spelled into the same; 1 means that when the query is complete.</p>
<img src="https://blog.netlab.360.com/content/images/2022/03/b1t_tun.png" width="860px">
<p>Let's take a look at the actual generated query <code>1HQoOKPvBKs8yqO1tTUQkCqGWN9anB4RAGWhnJy8A.dns.webserv.systems</code>, removing the first 5 bytes, and the .dns.webserv.systems part to get <code>KPvBKs8yqO1tTUQkCqGWN9anB4RAGWhnJy8A</code>, then use Base64 decoding, RC4 decryption, ZLIB decompression, you can get the following raw data.</p>
<img src="https://blog.netlab.360.com/content/images/2022/03/b1t_origin.png" width="860px">
<p>From the data content and format, it can correspond with our previous description one by one, indicating that our previous analysis is correct.</p>
<pre><code>Botid =0x125d
Stage=1
sysinfo.uptime = 34
uid=30
hostname=debian
</code></pre>
<h2 id="0x3senddnsrequest">0x3:Send DNS request</h2>
<p>When the above domain name construction is complete, B1txor20 generates and sends DNS requests using the RES series API.</p>
<img src="https://blog.netlab.360.com/content/images/2022/03/b1t_senddns.png" width="860px">
<p>There are 3 ways to send DNS requests, depending on the previous test of DNS connectivity.</p>
<p>1.Send to public dns (8.8.8.8, 8.8.4.4)<br>
2.Send directly to C2 (194.165.16.24)<br>
3.Send to local dns (nameserver in /etc/resolv.conf)</p>
<p>In this way, it is faster, but less concealed and easy to be detected and traced; in this way, 1 and 3 are more concealed, but a little slower.</p>
<h2 id="0x4processc2payload">0x4:Process C2 payload</h2>
<p>After the Bot sends the DNS request in the above way, it waits for the execution of the C2 instruction, which is stored in the response message of the DNS request in the format of <code>Status(1 byte):Body</code>, where the Body part also uses &quot;ZLIB compression, RC4 encryption, BASE64 encoding &quot; protection method.</p>
<img src="https://blog.netlab.360.com/content/images/2022/03/b1t_recv.png" width="860px">
<p>For example, the actual command &quot;1VSE6NZwczNMm2zgaXeLkZro=&quot; is received in the following figure.</p>
<img src="https://blog.netlab.360.com/content/images/2022/03/b1t_cmd.png" width="860px">
<p>Body part for &quot;VSE6NZwczNMm2zgaXeLkZro=&quot;, After decoded by Base64, RC4 decryption, you can get the following format of data, and then decompression of the<code>red part</code>, you get the final instruction <code>FF 02 FF 0A FF</code>, you can see that its format and the format generated by the above query is consistent, at this point it can be known that Bot will go to perform 0x02 function, so that Bot's round of interaction with C2 is complete.</p>
<img src="https://blog.netlab.360.com/content/images/2022/03/b1t_after.png" width="860px">
<h2 id="ccinstructions">C&amp;C instructions</h2>
<p>B1txor20 supports a total of 14 instructions, and the correspondence between instruction number and function is shown in the following table.</p>
<table>
<thead>
<tr>
<th>Cmd ID</th>
<th>Function</th>
</tr>
</thead>
<tbody>
<tr>
<td>0x1</td>
<td>Beacon/Heartbeat</td>
</tr>
<tr>
<td>0x2</td>
<td>Upload system info</td>
</tr>
<tr>
<td>0x3</td>
<td>Create &quot;/dev/pamd&quot; (unix domain socket) which can get a shell</td>
</tr>
<tr>
<td>0x4</td>
<td>Exec arbitrary system cmd via popen</td>
</tr>
<tr>
<td>0x5</td>
<td>Traffic forwarding</td>
</tr>
<tr>
<td>0x6</td>
<td>Write File</td>
</tr>
<tr>
<td>0x7</td>
<td>Read File</td>
</tr>
<tr>
<td>0x8</td>
<td>Deliver info via &quot;/var/tmp/.unetns&quot;(unix domain socket)，Not used</td>
</tr>
<tr>
<td>0x9</td>
<td>Upload specific info，Not used</td>
</tr>
<tr>
<td>0x10</td>
<td>Stop proxy service</td>
</tr>
<tr>
<td>0x11</td>
<td>Start proxy  service</td>
</tr>
<tr>
<td>0x1a</td>
<td>Create proxy service</td>
</tr>
<tr>
<td>0x21</td>
<td>Reverse shell</td>
</tr>
<tr>
<td>0x50</td>
<td>Upload &quot;/boot/conf- XXX&quot; info，Not used</td>
</tr>
<tr>
<td>0x51</td>
<td>install M3T4M0RPH1N3.ko rootkit</td>
</tr>
</tbody>
</table>
<p>In the table, &quot;Not used&quot; means that this function has the corresponding processing code in the sample, but it is not called. We are not sure if these codes are used for debugging or in other scenarios.</p>
<p>We found that some functions are buggy in their implementation, such as 0x3, which uses the remove function to delete the socket file after bind the domain socket, which makes the socket unconnectable and thus the whole function is useless.</p>
<img src="https://blog.netlab.360.com/content/images/2022/03/b1t_bug.png" width="860px">
<h2 id="smallnote">Small note</h2>
<p>We noticed the domain name has been registered for 6 years, which is kind unusual?</p>
<pre><code>webserv.systems	createddate                 2021-02-08 15:13:22
webserv.systems	updateddate                 2021-02-24 22:27:23
webserv.systems	expiresdate                 2027-02-08 15:13:22
</code></pre>
<h2 id="contactus">Contact us</h2>
<p>Readers are always welcomed to reach us on <a href="https://twitter.com/360Netlab">Twitter</a> or email us to netlab at 360 dot cn.</p>
<h2 id="ioc">IOC</h2>
<h3 id="c2">C2</h3>
<pre><code>webserv.systems
194.165.16.24:53
194.165.16.24:443
</code></pre>
<h3 id="scanner">Scanner</h3>
<pre><code>104.244.73.126	Luxembourg|Luxembourg|Unknown	53667|FranTech_Solutions
109.201.133.100	Netherlands|North_Holland|Amsterdam	43350|NForce_Entertainment_B.V.
162.247.74.27	United_States|New_York|New_York_City	4224|The_Calyx_Institute
166.78.48.7	United_States|Texas|Dallas	33070|Rackspace_Hosting
171.25.193.78	Sweden|Stockholm_County|Stockholm	198093|Foreningen_for_digitala_fri-_och_rattigheter
185.100.87.202	Romania|Bucharest|Unknown	200651|Flokinet_Ltd
185.129.62.62	Denmark|Region_Hovedstaden|Copenhagen	57860|Zencurity_ApS
185.220.100.240	Germany|Bavaria|Nuremberg	205100|F3_Netze_e.V.
185.220.100.241	Germany|Bavaria|Nuremberg	205100|F3_Netze_e.V.
185.220.100.242	Germany|Bavaria|Nuremberg	205100|F3_Netze_e.V.
185.220.100.243	Germany|Bavaria|Nuremberg	205100|F3_Netze_e.V.
185.220.100.246	Germany|Bavaria|Nuremberg	205100|F3_Netze_e.V.
185.220.100.249	Germany|Bavaria|Nuremberg	205100|F3_Netze_e.V.
185.220.100.250	Germany|Bavaria|Nuremberg	205100|F3_Netze_e.V.
185.220.100.252	Germany|Bavaria|Nuremberg	205100|F3_Netze_e.V.
185.220.100.254	Germany|Bavaria|Nuremberg	205100|F3_Netze_e.V.
185.220.100.255	Germany|Bavaria|Nuremberg	205100|F3_Netze_e.V.
185.220.101.134	Netherlands|North_Holland|Amsterdam	200052|Feral.io_Ltd
185.220.101.136	Netherlands|North_Holland|Amsterdam	200052|Feral.io_Ltd
185.220.101.140	Netherlands|North_Holland|Amsterdam	200052|Feral.io_Ltd
185.220.101.143	Netherlands|North_Holland|Amsterdam	200052|Feral.io_Ltd
185.220.101.144	Netherlands|North_Holland|Amsterdam	200052|Feral.io_Ltd
185.220.101.151	Netherlands|North_Holland|Amsterdam	200052|Feral.io_Ltd
185.220.101.155	Netherlands|North_Holland|Amsterdam	200052|Feral.io_Ltd
185.220.101.161	Netherlands|North_Holland|Amsterdam	200052|Feral.io_Ltd
185.220.101.162	Netherlands|North_Holland|Amsterdam	200052|Feral.io_Ltd
185.220.101.164	Netherlands|North_Holland|Amsterdam	200052|Feral.io_Ltd
185.220.101.166	Netherlands|North_Holland|Amsterdam	200052|Feral.io_Ltd
185.220.101.168	Netherlands|North_Holland|Amsterdam	200052|Feral.io_Ltd
185.220.101.172	Netherlands|North_Holland|Amsterdam	200052|Feral.io_Ltd
185.220.101.174	Netherlands|North_Holland|Amsterdam	200052|Feral.io_Ltd
185.220.101.176	Netherlands|North_Holland|Amsterdam	200052|Feral.io_Ltd
185.220.101.181	Netherlands|North_Holland|Amsterdam	200052|Feral.io_Ltd
185.220.101.191	Netherlands|North_Holland|Amsterdam	200052|Feral.io_Ltd
185.220.101.34	Netherlands|North_Holland|Amsterdam	200052|Feral.io_Ltd
185.220.101.37	Netherlands|North_Holland|Amsterdam	200052|Feral.io_Ltd
185.220.101.39	Netherlands|North_Holland|Amsterdam	200052|Feral.io_Ltd
185.220.101.40	Netherlands|North_Holland|Amsterdam	200052|Feral.io_Ltd
185.220.101.42	Netherlands|North_Holland|Amsterdam	200052|Feral.io_Ltd
185.220.101.43	Netherlands|North_Holland|Amsterdam	200052|Feral.io_Ltd
185.220.101.46	Netherlands|North_Holland|Amsterdam	200052|Feral.io_Ltd
185.220.101.5	Netherlands|North_Holland|Amsterdam	200052|Feral.io_Ltd
185.220.101.50	Netherlands|North_Holland|Amsterdam	200052|Feral.io_Ltd
185.220.101.51	Netherlands|North_Holland|Amsterdam	200052|Feral.io_Ltd
185.220.101.53	Netherlands|North_Holland|Amsterdam	200052|Feral.io_Ltd
185.220.101.54	Netherlands|North_Holland|Amsterdam	200052|Feral.io_Ltd
185.220.101.56	Netherlands|North_Holland|Amsterdam	200052|Feral.io_Ltd
185.220.101.57	Netherlands|North_Holland|Amsterdam	200052|Feral.io_Ltd
185.220.101.61	Netherlands|North_Holland|Amsterdam	200052|Feral.io_Ltd
185.56.80.65	Netherlands|South_Holland|Capelle_aan_den_IJssel	43350|NForce_Entertainment_B.V.
193.218.118.158	Ukraine|Kiev|Unknown	None;
194.32.107.159	Romania|Romania|Unknown	None;
194.32.107.187	Romania|Romania|Unknown	None;
194.88.143.66	Italy|Lombardy|Metropolitan_City_of_Milan	49367|Seflow_S.N.C._Di_Marco_Brame'_&amp;_C.
199.195.250.77	United_States|New_York|New_York_City	53667|FranTech_Solutions
23.129.64.216	United_States|Washington|Seattle	396507|Emerald_Onion
23.154.177.4	North_America_Regions|North_America_Regions|Unknown	None;
45.13.104.179	France|Ile-de-France|Paris	57199|MilkyWan
45.154.255.147	Sweden|Stockholm_County|Stockholm	41281|KeFF_Networks_Ltd
45.61.185.90	United_States|United_States|Unknown	8100|QuadraNet_Enterprises_LLC
46.166.139.111	Netherlands|South_Holland|Capelle_aan_den_IJssel	43350|NForce_Entertainment_B.V.
5.2.69.50	Netherlands|Flevoland|Dronten	60404|Liteserver_Holding_B.V.
51.15.43.205	Netherlands|North_Holland|Haarlem	12876|Online_S.a.s.
62.102.148.68	Sweden|Stockholm_County|Akersberga	51815|IP-Only_Networks_AB
62.102.148.69	Sweden|Stockholm_County|Akersberga	51815|IP-Only_Networks_AB
81.17.18.62	Switzerland|Canton_of_Ticino|Unknown	51852|Private_Layer_INC
</code></pre>
<h3 id="downloader">Downloader</h3>
<pre><code>hxxp://179.60.150.23:8000/xExportObject.class
ldap://179.60.150.23:1389/o=tomcat
hxxp://194.165.16.24:8229/b1t_1t.sh
hxxp://194.165.16.24:8228/b1t
hxxp://194.165.16.24:8228/b1t
hxxp://194.165.16.24:8228/_run.sh
hxxp://194.165.16.24:8228/run.sh
hxxp://194.165.16.24:8228/share.sh
hxxp://194.165.16.24:8228/b1t
hxxp://194.165.16.24:8228/run.sh
hxxp://194.165.16.24:8228/run.sh
hxxp://194.165.16.24:8229/b4d4b1t.elf
</code></pre>
<h3 id="samplemd5">Sample MD5</h3>
<pre><code>027d74534a32ba27f225fff6ee7a755f
0a0c43726fd256ad827f4108bdf5e772
24c49e4c75c6662365e10bbaeaeecb04
2e5724e968f91faaf156c48ec879bb40
3192e913ed0138b2de32c5e95146a24a
40024288c0d230c0b8ad86075bd7c678
43fcb5f22a53a88e726ebef46095cd6b
59690bd935184f2ce4b7de0a60e23f57
5f77c32c37ae7d25e927d91eb3b61c87
6b42a9f10db8b11a15006abced212fa4
6c05637c29b347c28d05b937e670c81e
7ef9d37e18b48de4b26e5d188a383ec8
7f4e74e15fafaf3f8b79254558019d7f
989dd7aa17244da78309d441d265613a
dd4b6e2750f86f2630e3aea418d294c0
e82135951c3d485b7133b9673194a79e
fd84b2f06f90940cb920e20ad4a30a63

</code></pre>

                    </div>
                </section>


                <footer class="post-full-footer">


                    <section class="post-full-authors">

    <div class="post-full-authors-content">
        <p>This post was a collaboration between</p>
        <p><a href="/author/alex/">Alex.Turing</a>, <a href="/author/huiwang/">Hui Wang</a></p>
    </div>

    <ul class="author-list">
        <li class="author-list-item">

            <div class="author-card">
                <div class="basic-info">
                        <img class="author-profile-image" src="https://blog.netlab.360.com/content/images/size/w100/2019/06/turing.PNG" alt="Alex.Turing" />
                    <h2>Alex.Turing</h2>
                </div>
                <div class="bio">
                        <p>Read <a href="/author/alex/">more posts</a> by this author.</p>
                </div>
            </div>

                <a href="/author/alex/" class="moving-avatar">
                    <img class="author-profile-image" src="https://blog.netlab.360.com/content/images/size/w100/2019/06/turing.PNG" alt="Alex.Turing" />
                </a>

        </li>
        <li class="author-list-item">

            <div class="author-card">
                <div class="basic-info">
                        <img class="author-profile-image" src="https://blog.netlab.360.com/content/images/size/w100/2017/05/WechatIMG1.jpeg" alt="Hui Wang" />
                    <h2>Hui Wang</h2>
                </div>
                <div class="bio">
                        <p>Read <a href="/author/huiwang/">more posts</a> by this author.</p>
                </div>
            </div>

                <a href="/author/huiwang/" class="moving-avatar">
                    <img class="author-profile-image" src="https://blog.netlab.360.com/content/images/size/w100/2017/05/WechatIMG1.jpeg" alt="Hui Wang" />
                </a>

        </li>

    </ul>

</section>


                </footer>

                <div id="disqus_thread"></div>
                <script>
                    var disqus_config = function () {
                        this.page.url = "https://blog.netlab.360.com/b1txor20-use-of-dns-tunneling_en/";
                        this.page.identifier = "ghost-62305717a5c41b00078fca48"
                    };
                    (function () {
                        var d = document, s = d.createElement('script');
                        s.src = 'https://blog-netlab-360.disqus.com/embed.js';
                        s.setAttribute('data-timestamp', +new Date());
                        (d.head || d.body).appendChild(s);
                    })();
                </script>

            </article>

        </div>
    </main>

    <aside class="read-next outer">
        <div class="inner">
            <div class="read-next-feed">
                <article class="read-next-card"   style="background-image: url(https://blog.netlab.360.com/content/images/size/w600/2019/02/astronomy-constellation-dark-998641-4.jpg)"
                     >
                    <header class="read-next-card-header">
                        <small class="read-next-card-header-sitetitle">&mdash; 360 Netlab Blog - Network Security Research Lab at 360 &mdash;</small>
                        <h3 class="read-next-card-header-title"><a href="/tag/botnet/">Botnet</a></h3>
                    </header>
                    <div class="read-next-divider"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M13 14.5s2 3 5 3 5.5-2.463 5.5-5.5S21 6.5 18 6.5c-5 0-7 11-12 11C2.962 17.5.5 15.037.5 12S3 6.5 6 6.5s4.5 3.5 4.5 3.5"/></svg>
</div>
                    <div class="read-next-card-content">
                        <ul>
                            <li><a href="/b1txor20-use-of-dns-tunneling_cn/">新威胁：使用DNS Tunnel技术的Linux后门B1txor20正在通过Log4j漏洞传播</a></li>
                            <li><a href="/some_details_of_the_ddos_attacks_targeting_ukraine_and_russia_in_recent_days/">Some details of the DDoS attacks targeting Ukraine and Russia in recent days</a></li>
                            <li><a href="/wo-men-kan-dao-de-wu-ke-lan-bei-ddosgong-ji-xi-jie/">我们近期看到的针对乌克兰和俄罗斯的DDoS攻击细节</a></li>
                        </ul>
                    </div>
                    <footer class="read-next-card-footer">
                        <a href="/tag/botnet/">See all 102 posts →</a>
                    </footer>
                </article>

                <article class="post-card post no-image">


    <div class="post-card-content">

        <a class="post-card-content-link" href="/shu-zi-zheng-shu-zuo-wei-ji-chu-she-shi-de-shi-yong-qing-kuang-fen-xi/">

            <header class="post-card-header">
                <h2 class="post-card-title">商业数字证书签发和使用情况简介(删减版)</h2>
            </header>

            <section class="post-card-excerpt">
                <p>概要数字证书是整个现代webPKI系统的最核心的部分之一。如果说DNS数据标识了网络资产的地址，那么数字证书就是网络资产的身份证。没有,丢失或者被吊销数字证书，就没有办法证明“我”就是“我”。因此PKI系统及其数据已经成为网络真正的基础设施，作为互联网安全运营的基础数据，重要性不言而喻。 3月初,乌克兰政府向互联网域名管理结构ICANN书面请求将俄罗斯相关顶级域名“.ru”, “.рф” 和“.su”从互联网撤销[1]，但ICANN并没有认同这份请求[2]。近日，我们注意到俄罗斯相关的一些国家基础设施网站的证书被证书机构陆续吊销。 360Netlab成立之后不久就通过主动、被动相结合的方式收集网络数字证书，并以此为基础构建了网络证书数据库CertDB。目前该库包含证书规模和涉及的IP端口数据达到十亿级，历史数据可追溯超过5年，是360Netlab基础数据分析系统DNSMon的重要组成部分。此外360Netlab同时运营着的网络空间基础数据库包括描述域名注册的WhoisDB、域名解析的PassiveDNS、网站页面的WebDB等等。</p>
            </section>

        </a>

        <footer class="post-card-meta">

            <ul class="author-list">
                <li class="author-list-item">

                    <div class="author-name-tooltip">
                        Zhang Zaifeng
                    </div>

                        <a href="/author/zhangzaifeng-2/" class="static-avatar">
                            <img class="author-profile-image" src="https://blog.netlab.360.com/content/images/size/w100/2016/09/ant.jpg" alt="Zhang Zaifeng" />
                        </a>
                </li>
            </ul>

            <span class="reading-time">14 min read</span>

        </footer>

    </div>

</article>

                <article class="post-card post tag-botnet tag-dns-tunnel tag-dns tag-backdoor no-image">


    <div class="post-card-content">

        <a class="post-card-content-link" href="/b1txor20-use-of-dns-tunneling_cn/">

            <header class="post-card-header">
                    <span class="post-card-tags">Botnet</span>
                <h2 class="post-card-title">新威胁：使用DNS Tunnel技术的Linux后门B1txor20正在通过Log4j漏洞传播</h2>
            </header>

            <section class="post-card-excerpt">
                <p>背景 自从Log4J漏洞被曝光后，正所谓&quot;忽如一夜漏洞来，大黑小灰笑开怀”。无数黑产团伙摩拳擦掌加入了这个“狂欢派对”，其中既有许多业界非常熟悉的恶意软件家族，同时也有一些新兴势力想趁着这股东风在黑灰产上分一杯羹。360Netlab作为专注于蜜罐和Botnet检测跟踪的团队，我们自该漏洞被公开后就一直关注它会被哪些僵尸网络利用，期间我们看到了Elknot，Gafgyt，Mirai等老朋友的从不缺席，也见证了一些新朋友的粉墨登场。 2022年2月9日，360Netlab的蜜罐系统捕获了一个未知的ELF文件通过Log4J漏洞传播，此文件在运行时产生的网络流量引发了疑似DNS Tunnel的告警，这引起了我们的兴趣。经过分析，我们确定是一个全新的僵尸网络家族，基于其传播时使用的文件名&quot;b1t&quot;，XOR加密算法，以及RC4算法秘钥长度为20字节，它被我们命名为B1txor20。 简单来说，B1txor20是一个针对Linux平台的后门木马， 它利用DNS</p>
            </section>

        </a>

        <footer class="post-card-meta">

            <ul class="author-list">
                <li class="author-list-item">

                    <div class="author-name-tooltip">
                        Alex.Turing
                    </div>

                        <a href="/author/alex/" class="static-avatar">
                            <img class="author-profile-image" src="https://blog.netlab.360.com/content/images/size/w100/2019/06/turing.PNG" alt="Alex.Turing" />
                        </a>
                </li>
                <li class="author-list-item">

                    <div class="author-name-tooltip">
                        Hui Wang
                    </div>

                        <a href="/author/huiwang/" class="static-avatar">
                            <img class="author-profile-image" src="https://blog.netlab.360.com/content/images/size/w100/2017/05/WechatIMG1.jpeg" alt="Hui Wang" />
                        </a>
                </li>
            </ul>

            <span class="reading-time">14 min read</span>

        </footer>

    </div>

</article>

            </div>
        </div>
    </aside>

    <div class="floating-header">
    <div class="floating-header-logo">
        <a href="https://blog.netlab.360.com">
                <img src="https://blog.netlab.360.com/content/images/size/w30/2019/02/netlab_xs-2.png" alt="360 Netlab Blog - Network Security Research Lab at 360 icon" />
            <span>360 Netlab Blog - Network Security Research Lab at 360</span>
        </a>
    </div>
    <span class="floating-header-divider">&mdash;</span>
    <div class="floating-header-title">New Threat: B1txor20, A Linux Backdoor Using DNS Tunnel</div>
    <div class="floating-header-share">
        <div class="floating-header-share-label">Share this <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
    <path d="M7.5 15.5V4a1.5 1.5 0 1 1 3 0v4.5h2a1 1 0 0 1 1 1h2a1 1 0 0 1 1 1H18a1.5 1.5 0 0 1 1.5 1.5v3.099c0 .929-.13 1.854-.385 2.748L17.5 23.5h-9c-1.5-2-5.417-8.673-5.417-8.673a1.2 1.2 0 0 1 1.76-1.605L7.5 15.5zm6-6v2m-3-3.5v3.5m6-1v2"/>
</svg>
</div>
        <a class="floating-header-share-tw" href="https://twitter.com/share?text=New%20Threat%3A%20B1txor20%2C%20A%20Linux%20Backdoor%20Using%20DNS%20Tunnel&amp;url=https://blog.netlab.360.com/b1txor20-use-of-dns-tunneling_en/"
            onclick="window.open(this.href, 'share-twitter', 'width=550,height=235');return false;">
            <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32"><path d="M30.063 7.313c-.813 1.125-1.75 2.125-2.875 2.938v.75c0 1.563-.188 3.125-.688 4.625a15.088 15.088 0 0 1-2.063 4.438c-.875 1.438-2 2.688-3.25 3.813a15.015 15.015 0 0 1-4.625 2.563c-1.813.688-3.75 1-5.75 1-3.25 0-6.188-.875-8.875-2.625.438.063.875.125 1.375.125 2.688 0 5.063-.875 7.188-2.5-1.25 0-2.375-.375-3.375-1.125s-1.688-1.688-2.063-2.875c.438.063.813.125 1.125.125.5 0 1-.063 1.5-.25-1.313-.25-2.438-.938-3.313-1.938a5.673 5.673 0 0 1-1.313-3.688v-.063c.813.438 1.688.688 2.625.688a5.228 5.228 0 0 1-1.875-2c-.5-.875-.688-1.813-.688-2.75 0-1.063.25-2.063.75-2.938 1.438 1.75 3.188 3.188 5.25 4.25s4.313 1.688 6.688 1.813a5.579 5.579 0 0 1 1.5-5.438c1.125-1.125 2.5-1.688 4.125-1.688s3.063.625 4.188 1.813a11.48 11.48 0 0 0 3.688-1.375c-.438 1.375-1.313 2.438-2.563 3.188 1.125-.125 2.188-.438 3.313-.875z"/></svg>
        </a>
        <a class="floating-header-share-fb" href="https://www.facebook.com/sharer/sharer.php?u=https://blog.netlab.360.com/b1txor20-use-of-dns-tunneling_en/"
            onclick="window.open(this.href, 'share-facebook','width=580,height=296');return false;">
            <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32"><path d="M19 6h5V0h-5c-3.86 0-7 3.14-7 7v3H8v6h4v16h6V16h5l1-6h-6V7c0-.542.458-1 1-1z"/></svg>
        </a>
    </div>
    <progress id="reading-progress" class="progress" value="0">
        <div class="progress-container">
            <span class="progress-bar"></span>
        </div>
    </progress>
</div>




        <footer class="site-footer outer">
            <div class="site-footer-content inner">
                <section class="copyright"><a href="https://blog.netlab.360.com">360 Netlab Blog - Network Security Research Lab at 360</a> &copy; 2022</section>
                <nav class="site-footer-nav">
                    <a href="https://blog.netlab.360.com">Latest Posts</a>
                    
                    <a href="https://twitter.com/360Netlab" target="_blank" rel="noopener">Twitter</a>
                    <a href="https://ghost.org" target="_blank" rel="noopener">Ghost</a>
                </nav>
            </div>
        </footer>

    </div>


    <script>
        var images = document.querySelectorAll('.kg-gallery-image img');
        images.forEach(function (image) {
            var container = image.closest('.kg-gallery-image');
            var width = image.attributes.width.value;
            var height = image.attributes.height.value;
            var ratio = width / height;
            container.style.flex = ratio + ' 1 0%';
        })
    </script>


    <script
        src="https://code.jquery.com/jquery-3.2.1.min.js"
        integrity="sha256-hwg4gsxgFZhOsEEamdOYGBf13FyQuiTwlAQgxVSNgt4="
        crossorigin="anonymous">
    </script>
    <script type="text/javascript" src="/assets/built/jquery.fitvids.js?v=a1b70de19f"></script>


    <script>
// Adds delay to author card dropups to disappear. This gives enough
// time for the user to interact with the author card while they move
// the mouse from the avatar to the card. Also makes space for the
// interacted avatar.
$(document).ready(function () {

    var hoverTimeout;

    $('.author-list-item').hover(function(){
        var $this = $(this);

        clearTimeout(hoverTimeout);

        $('.author-card').removeClass('hovered');
        $(this).children('.author-card').addClass('hovered');

    }, function() {
        var $this = $(this);

        hoverTimeout = setTimeout(function() {
            $this.children('.author-card').removeClass('hovered');
        }, 800);
    });

});
</script>

    <script>

        // NOTE: Scroll performance is poor in Safari
        // - this appears to be due to the events firing much more slowly in Safari.
        //   Dropping the scroll event and using only a raf loop results in smoother
        //   scrolling but continuous processing even when not scrolling
        $(document).ready(function () {
            // Start fitVids
            var $postContent = $(".post-full-content");
            $postContent.fitVids();
            // End fitVids

            var progressBar = document.querySelector('#reading-progress');
            var header = document.querySelector('.floating-header');
            var title = document.querySelector('.post-full-title');

            var lastScrollY = window.scrollY;
            var lastWindowHeight = window.innerHeight;
            var lastDocumentHeight = $(document).height();
            var ticking = false;

            function onScroll() {
                lastScrollY = window.scrollY;
                requestTick();
            }

            function onResize() {
                lastWindowHeight = window.innerHeight;
                lastDocumentHeight = $(document).height();
                requestTick();
            }

            function requestTick() {
                if (!ticking) {
                    requestAnimationFrame(update);
                }
                ticking = true;
            }

            function update() {
                var trigger = title.getBoundingClientRect().top + window.scrollY;
                var triggerOffset = title.offsetHeight + 35;
                var progressMax = lastDocumentHeight - lastWindowHeight;

                // show/hide floating header
                if (lastScrollY >= trigger + triggerOffset) {
                    header.classList.add('floating-active');
                } else {
                    header.classList.remove('floating-active');
                }

                progressBar.setAttribute('max', progressMax);
                progressBar.setAttribute('value', lastScrollY);

                ticking = false;
            }

            window.addEventListener('scroll', onScroll, { passive: true });
            window.addEventListener('resize', onResize, false);

            update();

        });
    </script>


    

</body>
</html>
